Boost.MSM(Meta State Machine, MSM)은 Boost에서 제공되는 상태 머신 라이브러리이다.
CRTP(Curiously_recurring_template_pattern) 형태로 state_machine_def를 상속받아
사용한다.
struct PhoneStateMachine: state_machine_def<PhoneStateMachine>{
bool angry{false};
};
각각의 상태는 state 클래스를 상속받아야 상태 머신안에 들어갈 수 있다.
struct OffHook: state<> {};
struct Connecting: state<> {
template <class Event, class FSM>
void on_entry(Event const& evt, FSM&){
cout<<"we are connecting..."<<endl;
}
};
상태 전이 시점에 수행되어야 하는 동작도 정의할 수 있다.
struct PhoneBeingDestroyed{
template <class EVT, class FSM, class SourceState, class TargetState>
void operator()(EVT const&, FSM&, SourceState&, TargetState&){
cout<<"Phone breaks into a million pieces"<<endl;
}
};
보호조건:
산태 전이를 수행하기 전에 유효한 전이인지 아닌지를 검사함
struct CanDestroyPhone{
template <class EVT, class FSM, class SourceState, class TargetState>
bool operator()(EVT const&, FSM& fsm, SourceState&, TargetState&){
return fsm.angry;
}
};
상태 머신 규칙을 정의하기 위해서
Boost.MSM은 MPL(메타 프로그래밍 라이브러리)를 사용한다.
mpl::vector
- 출발 상태
- 상태 전이
- 도착 상태
- 부가적인 동작(옵션)
- 부가적인 보호 조건(옵션)
struct transition_table: mpl::vector<row<OffHook, CallDialed, Connecting>, row<Connecting, CallConnected, Connected>, row<Connected, PlacedOnHold, OnHold>, row<OnHold, PhoneThrownIntoWall, PhoneDestroyed, PhoneBeingDestryed, CanDestroyPhone>> {};
시작 조건 추가
typedef OffHook initial_state;
상태 전이가 불가능할 때 수행할 동작 정의
template <class FSM, class Event>
void no_transition(Event const& e, FSM&, int state){
cout<<"No transition from state "<<state_names[state]<<" on event "<<typeid(e).name()<<endl;
}
백엔드 API를 이용해 정의한 상태 머신을 생성
msm::back::state_machine<PhoneStateMachine> phone;
info();
phone.process_event(CallDialed{});
info();
phone.process_event(CallConnected{});
info();
phone.process_event(PlacedOnHold{});
info();
phone.process_event(PhoneThrownIntoWall{});
info();
phone.process_event(CallDialed{});
Boost는 대표적으로 Boost.MSM 와 Boost.Statechart를 통해 상태 머신 라이브러리를 지원한다.